package com.onpositive.knowledge.model.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import com.onpositive.knowledge.model.IAuditedUniverse;
import com.onpositive.knowledge.model.IThing;
import com.onpositive.knowledge.model.IType;
import com.onpositive.knowledge.model.ThingFilter;
import com.onpositive.knowledge.model.value.audits.AbstractAuditResult;
import com.onpositive.knowledge.model.value.audits.IAuditManager;
import com.onpositive.knowledge.model.value.audits.IValueAudit;
import com.onpositive.semantic.model.api.meta.IHasMeta;
import com.onpositive.semantic.model.api.property.IProperty;
import com.onpositive.semantic.model.api.realm.IRealm;
import com.onpositive.semantic.model.api.realm.Realm;

public abstract class BasicUniverse implements IAuditedUniverse {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	protected IRealm<BasicUniverseProperty> propertiesRealm;

	protected AbstractAuditResult auditResult;

	protected IAuditManager auditManager ; //AllPropertiesAudit mainAudit;

	protected IRealm<BasicUniverseProperty> createPropertiesRealm() {
		return new Realm<BasicUniverseProperty>();
	}

	protected IRealm<IThing> allThings;

	protected IRealm<IThing> createRealm() {
		return new Realm<IThing>();
	}

	protected Realm<IType> allTypes;

	@Override
	public IProperty getProperty(Object obj, String name) {
		return null;
	}

	@Override
	public Iterable<IProperty> getProperties(Object obj) {
		return allProperties();
	}

	@Override
	public IRealm<IThing> all() {
		if (allThings == null) {
			allThings = createRealm();
		}
		return allThings;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public IRealm<IProperty> allProperties() {
		if (propertiesRealm == null) {
			propertiesRealm = createPropertiesRealm();
		}
		return (IRealm) propertiesRealm;
	}

	public abstract void initAuditManager() ;
	
	@Override
	public AbstractAuditResult getAuditResult() {
		if( auditResult == null )
		{
			if( auditManager == null )
				initAuditManager() ;
			
			auditResult = auditManager.getAuditResult() ;
		}
		
		return auditResult;
	}
	

	@Override
	public void launchAudit()
	{
		if( auditManager == null ){
			initAudit() ;
		}

		Collection<IThing> all = all().getContents() ;
		ArrayList<Object> arg = new ArrayList<Object>(all) ;

		auditResult = auditManager.createAuditResult() ;
		auditManager.perform(null, arg, auditResult ) ;
	}
	
	protected void processGeneralResult(AbstractAuditResult perform, IValueAudit a)
	{

	}

	protected Collection<IValueAudit> getGeneralAuditors(){
		return Collections.emptySet();		
	}

	
	
	
	@Override
	public IAuditManager getAuditManager() {
		if( auditManager == null )
			initAudit() ;
		
		return auditManager;
	}

	protected void initAudit() {
		
		
	}

	@Override
	public IRealm<IThing> getRealm(IHasMeta model, Object parentObject,	Object object)
	{		
		if( parentObject == null )
			return all() ;
		
		if( !(parentObject instanceof IThing ) )
			return null ;

		IThing root = (IThing) parentObject ;
		
		return ThingFilter.filter( all(), root) ;
	}

}
